package pl.mchaniewski.ryneczek.screenscrapping.impl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import pl.mchaniewski.ryneczek.pojo.Quotation;
import pl.mchaniewski.ryneczek.screenscrapping.ArchiveQuotations;

@Component("archiveQuotations")
public class BossaPlScrapper implements ArchiveQuotations {
    private static final Logger logger = LoggerFactory
            .getLogger(BossaPlScrapper.class);
    private static String BOSSA_PL_URL = "http://bossa.pl/pub/ciagle/mstock/sesjacgl/";
    private static String BOSSA_LAST_DAY = "sesjacgl.prn";
    private static Integer NUMBER_OF_VALUES = 7;
    private static Integer NAME = 0;
    private static Integer DATE = 1;
    private static Integer OPEN_VALUE = 2;
    private static Integer MAXIMUM_VALUE = 3;
    private static Integer MINIMUM_VALUE = 4;
    private static Integer CURRENT_VALUE = 5;
    private static Integer TRADING_VOLUME = 6;
    private static String VALUE_SEPARATOR = ",";
    private static String DATE_FORMAT = "yyyyMMdd";

    private Map<String, Quotation> scrapHtml(String uri) {
        try {
            URL url = new URL(uri);

            BufferedReader in = new BufferedReader(new InputStreamReader(
                    url.openStream()));

            Map<String, Quotation> map = new LinkedHashMap<String, Quotation>(0);

            String str = null;
            String lastCompanyName = null;
            while ((str = in.readLine()) != null) {
                String[] splittedValues = str.split(VALUE_SEPARATOR);
                if (splittedValues.length != NUMBER_OF_VALUES) {
                    throw new Exception("Problem with prasing given string: "
                            + str + " Should split into " + NUMBER_OF_VALUES
                            + " values.");
                }

                String companyName = splittedValues[NAME];

                if (lastCompanyName != null && lastCompanyName.length() > 0
                        && companyName != null && companyName.length() > 0) {
                    char previous = lastCompanyName.toCharArray()[0];
                    char current = companyName.toCharArray()[0];

                    if (current < previous) {
                        break;
                    }
                }

                lastCompanyName = companyName;
                DateFormat df = new SimpleDateFormat(DATE_FORMAT);
                Date time = df.parse(splittedValues[DATE]);
                BigDecimal openValue = new BigDecimal(
                        splittedValues[OPEN_VALUE]);
                BigDecimal maxValue = new BigDecimal(
                        splittedValues[MAXIMUM_VALUE]);
                BigDecimal minValue = new BigDecimal(
                        splittedValues[MINIMUM_VALUE]);
                BigDecimal currentValue = new BigDecimal(
                        splittedValues[CURRENT_VALUE]);
                Integer tradingVolume = Integer
                        .parseInt(splittedValues[TRADING_VOLUME]);

                Quotation quot = new Quotation();
                quot.setOpenValue(openValue);
                quot.setMinimumValue(minValue);
                quot.setMaximumValue(maxValue);
                quot.setCurrentValue(currentValue);
                quot.setDailyChange(null);
                quot.setListingDate(time);
                quot.setTradingVolume(tradingVolume);
                quot.setMarketValue(null);

                map.put(companyName, quot);
            }
            in.close();

            return map;
        } catch (MalformedURLException ex) {
            logger.warn(
                    "Problems with given URL {} You migh want to update this class. Exception details: {}",
                    BOSSA_PL_URL, ex.getMessage());
        } catch (IOException ex) {
            logger.warn(
                    "Problems with stream from {} You migh want to update this class. Exception details: {}",
                    BOSSA_PL_URL, ex.getMessage());
        } catch (Exception ex) {
            logger.warn(
                    "Problems with parsing values. You migh want to update this class. Exception details: {}",
                    BOSSA_PL_URL, ex.getMessage());
        }

        return null;
    }

    @Override
    public Map<String, Quotation> getLastDayQuotes() {
        return scrapHtml(BOSSA_PL_URL + BOSSA_LAST_DAY);
    }

    @Override
    public Map<String, Quotation> getSpecificDayQuotes(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
        return scrapHtml(BOSSA_PL_URL + sdf.format(date) + ".prn");
    }

}
